<template>
  <view
    class="w-full h-full bg-green"
    @touchmove.stop.prevent="handleTouchMove"
  >
    <view class="trail-container" v-if="trailPoints.length > 0">
      <view
        v-for="(point, index) in trailPoints"
        :key="index"
        class="trail-point"
        :style="{
          left: point.x + 'px',
          top: point.y + 'px',
          opacity: point.opacity,
        }"
      ></view>
    </view>
  </view>
</template>

<script setup>
import { nextTick, ref } from "vue";
import { str2ab } from "../../utils/index";
import { throttle } from "lodash";
import { onLoad } from "@dcloudio/uni-app";

let list = [
  "0x01",
  "0x02",
  "0x03",
  "0x04",
  "0x05",
  "0x06",
  "0x07",
  "0x08",
  "0x09",
];

const x = ref(0);
const y = ref(0);

// 添加轨迹点数组
const trailPoints = ref([]);

const lastMsg = ref("");
const lastSpeed = ref(0);

const handleTouchMove = throttle((event) => {
  // 计算值差
  let diffX = event.touches[0].clientX - x.value;
  let diffY = event.touches[0].clientY - y.value;

  if (diffX < 0) {
    diffX = 0 - diffX;
  }

  if (diffY < 0) {
    diffY = 0 - diffY;
  }

  let speed = parseInt((diffX + diffY) % 9);

  if (speed < 0) {
    speed = 9 + speed;
  }

  handleShake(speed);

  x.value = event.touches[0].clientX;
  y.value = event.touches[0].clientY;

  // 添加轨迹点
  trailPoints.value.push({
    x: x.value,
    y: y.value,
    opacity: 1,
  });

  // 限制轨迹点数量，保持最新的20个
  if (trailPoints.value.length > 20) {
    trailPoints.value.shift();
  }

  // 轨迹点淡出动画
  setTimeout(() => {
    const point = trailPoints.value.find(
      (p) => p.x === x.value && p.y === y.value
    );
    if (point) {
      point.opacity = 0;
    }
  }, 200);
}, 10);

const timeout = ref(null);

// 处理摇一摇事件
const handleShake = throttle((speed) => {
  lastSpeed.value = speed;

  let msg = list[speed];

  if (msg === lastMsg.value) {
    return;
  }

  sendVibrationMode(msg);

  lastMsg.value = msg;
}, 1000);

const sendVibrationMode = (msg) => {
  // 向蓝牙设备发送一个0x00的16进制数据

  return new Promise((resolve, reject) => {
    let buffer = str2ab(msg);

    uni.writeBLECharacteristicValue({
      deviceId: deviceId.value,
      serviceId: serviceId.value,
      characteristicId: characteristicId.value,
      value: buffer,
      writeType: "write",
      success(res) {
        resolve(res);

        timeout.value = setTimeout(() => {
          sendVibrationMode("0x00");
        }, 1000);
      },
      fail(err) {
        reject(err);
      },
    });
  });
};

const deviceId = ref("");
const serviceId = ref("");
const characteristicId = ref("");
const name = ref("");
const advertisServiceUUIDs = ref([]);

onLoad(() => {
  deviceId.value = uni.getStorageSync("deviceId") || "";
  serviceId.value = uni.getStorageSync("serviceId") || "";
  characteristicId.value = uni.getStorageSync("characteristicId") || "";
  name.value = uni.getStorageSync("name") || "";
  advertisServiceUUIDs.value = uni.getStorageSync("advertisServiceUUIDs") || [];
});
</script>

<style lang="scss" scoped>
.top {
  z-index: 99999;
}

.w-full {
  width: 100vw;
}

.h-full {
  height: calc(100vh - 44px);
}

.bg-green {
  background-color: aquamarine;
}

.trail-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100vw;
  height: calc(100vh - 44px);
  pointer-events: none;
  z-index: 9999;
}

.trail-point {
  position: absolute;
  width: 20px;
  height: 20px;
  background-color: #cd1300;
  border-radius: 50%;
  // transition: opacity 0.5s ease-out;
}
</style>
